#!/usr/bin/env python
# encoding: utf-8
"""
tableclient.py

Created by 黄 冬 on 2007-12-19.
Copyright (c) 2007 __MyCompanyName__. All rights reserved.
"""

from twisted.internet import reactor,defer
from twisted.internet.protocol import Protocol, ClientFactory
from twisted.protocols.basic import Int16StringReceiver
import logging.config

log = logging.getLogger('xbaytable.tools.tableclient')
#logging.basicConfig(level=logging.ERROR)
#logging.basicConfig(level=logging.WARNING)
logging.basicConfig(level=logging.DEBUG)

from xbaytable.conf import *
from xbaytable.utils.tablemsg import *

class TableProtocol(Int16StringReceiver):
    """实现table protocol"""
    def stringReceived(self, msg):
        """有数据需要接收了"""
        command,sequence_id=self.process.recv_head(msg[0:4])
        log.debug('recv command %s,sequence %s'%(command['command_name'],sequence_id))
        self.sendwin.remove(sequence_id)
        if (command['command_id'] == 2):
            #如果没有bind认证通过，还不是一个bind的请求，哪么关闭这个新来的连接
            self.bind = True
            d = defer.maybeDeferred(self.sendTableSet)
            #d.addCallback(self.noSendLog)
            #self.transport.loseConnection()
        elif(self.bind):
            d = self.process_command(command,sequence_id,msg)
            #self.transport.loseConnection()

    def process_command(self,command,sequence_id,msg):
        """处理发来的请求"""
        d = defer.Deferred()
        eval('self.process.process_%s(self,command,sequence_id,msg[4:])'%command['command_name'])
        return d

    def connectionMade(self):
        """建立了连接后先发出table_bind请求进行认证"""
        #发送send报文的数量
        self.sendcount = 0
        #发送出去的报文窗口记录
        self.sendwin = []
        #是不是与服务器建立完成了bind认证
        self.bind=False
        #处理消息的对象进行初始化
        self.process =self.factory.process()
        #向服务器发出bind请求
        sequence_id = self.process.send_bind_table(self,TABLE_USERNAME,TABLE_PASSWORD)
        self.sendwin.append(sequence_id)

    def noSendLog(self,value):
        if self.sendwin>=TABLE_WIN_MAX :
            log.debug("sendTableSet return")
        else:
            log.debug("not bind to server")

    def sendTableSet(self):
        """向服务器发出set请求"""
        while (self.sendcount < self.factory.sendnum):
            if (len(self.sendwin)<TABLE_WIN_MAX):
                self.sendcount += 1
                msg = 'abc'
                for i in range(1,100):
                    msg +='********************************************************************************************************'
                sequence_id = self.process.send_table_set(self,'a%s'%self.sendcount,'%s%s'%(msg,self.sendcount))
                self.sendwin.append(sequence_id)
                log.info('send now socket_win is:%s'%len(self.sendwin))
            else:
                log.debug("window is full,window siz is:%s"%len(self.sendwin))
                reactor.callLater(0,self.sendTableSet)
                return

class TableClientFactory(ClientFactory):
    """客户端连接工厂类"""
    protocol=TableProtocol
    
    def __init__(self, sendnum, process):
        """sendnum为发送数量"""
        #发送测试报文的数量
        self.sendnum = sendnum
        self.process = process
        
    def clientConnectionFailed(self,connect,reason):
        """连接失败"""
        log.error('Connect failed.Reason:%s'%reason)
        reactor.stop()

    def clientConnectionLost(self, connector, reason):
        log.info('Connect Lost.')
        reactor.stop()

if __name__ == '__main__':
    sendnum = 10
    #reactor.connectTCP(TABLE_SERVER_IP, TABLE_SERVER_PORT, TableClientFactory(sendnum))
    reactor.connectTCP('127.0.0.1', TABLE_SERVER_PORT, TableClientFactory(sendnum,ProcessMessage))
    reactor.run()
